import numpy as np
import platgo as pg


class sogo_DE(pg.Algorithm):
    """
    应用于单目标的差分进化
    
    流程：
    1.
    """
    
    def __init__(self,N:int, maxgen:int, problem:pg.Problem) -> None:
        super().__init__(problem=problem, maxgen=maxgen)
        self.name = 'sogo_DE'
        self.mut = pg.operators.MutPol(problem.borders)  # 多项式变异
        self.crv = pg.operators.DE(F=0.5)  # 差分算子
        self.population = pg.Population(N=N, problem=problem)
    
    
    def go(self):
        population = self.population.copy()
        self.problem.cal_obj(population)  # 计算目标函数值
        
        while self.not_terminal(population):
            offspring = self.crv(population)
            offspring = self.mut(offspring)
            self.problem.cal_obj(offspring)  # 计算子代种群目标函数值
            temp_pop = offspring+population  # 合并种群
            # 返回目标值小的一半
            median = np.median(temp_pop.objv)
            ind = temp_pop.objv <= median
            temp_pop = temp_pop[ind]
            if len(temp_pop) > population.N:
                population = temp_pop[:population.N]
            else:
                population = temp_pop
            # 目标函数值求和应该是逐步减小的
            # print("current generation: {}, the sum of objective: {}".format(self.gen, np.mean(population.objv)))
        return population
            
            
            
        
        
        
    